# 14. 函数变量声明提升和优先级

# 变量声明和函数声明会被提升到作用域顶部

# 变量声明

a = 2;
var a;
console.log( a );//2

//提升后相当于
var a;
a = 2;
console.log( a );
1
2
3
4
5
6
7
8

# 函数声明

oecom();//oecom
function oecom(){
	console.log("oecom")
}

//提升后相当于
function oecom(){
  console.log("oecom")
}
oecom();//oecom
1
2
3
4
5
6
7
8
9
10

# 函数表达式不会被提升

oecom();//TypeError:oecom is not a function
var oecom = function(){
  console.log("oecom")
}

//提升后相当于
var oecom;
oecom();
oecom = function oecom(){
  console.log("oecom")
}
1
2
3
4
5
6
7
8
9
10
11

# 函数优先

函数声明和变量声明都会被提升。但函数会首先被提升,然后才是变量。

foo(); // 1
var foo;
function foo() {
 console.log( 1 );
}
foo = function() {
 console.log( 2 );
};

//提升后相当于
function foo() {
 console.log( 1 );
}
// var foo;//由于foo已被声明所以被忽略
foo(); // 1
foo = function() {
 console.log( 2 );
};
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

var foo 尽管出现在 function foo()... 的声明之前,但它是重复的声明(因此被忽略了),因为函数声明会被提升到普通变量之前。尽管重复的 var 声明会被忽略掉,但出现在后面的函数声明还是可以覆盖前面的。

foo(); // 3
function foo() {
 console.log( 1 );
}
var foo = function() {
 console.log( 2 );
};
foo()
function foo() {
 console.log( 3 );
}

//提升后相当于
function foo() {
 console.log( 1 );
}
function foo() {
 console.log( 3 );
}
//var foo;
foo(); // 3
foo = function() {
 console.log( 2 );
};
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
foo(); // "b"
var a = true;
if (a) {
 function foo() { console.log("a"); }
}
else {
 function foo() { console.log("b"); }
}

//块级作用域对于函数声明来说不起作用,提升后变为:
function foo() { console.log("a"); }
function foo() { console.log("b"); }
var a
foo(); // "b"
a = true;
if (a) {}
else {}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17